package com.tengju.bff.interfaces.manage.crm.dashborad.facade;

import com.tengju.bff.interfaces.shared.ColumnVO;
import com.tengju.bff.interfaces.shared.KVVO;
import com.tengju.bff.interfaces.shared.TableAssembler;
import com.tengju.bff.interfaces.shared.TableVO;
import com.tengju.bff.interfaces.shared.render.KVAssembler;
import com.tengju.bff.interfaces.shared.servlet.ServletContextUtil;
import com.tengju.data.domain.model.analysis.Meta;
import com.tengju.data.domain.model.analysis.MetaHolder;
import com.tengju.data.domain.model.analysis.Row;
import com.tengju.data.domain.model.report.performance.ReportPerformanceRepository;
import com.tengju.data.domain.shared.CastUtil;
import com.tengju.data.domain.shared.Week;
import com.tengju.motivation.domain.model.performance.PerformanceObjective;
import com.tengju.motivation.domain.model.performance.PerformanceObjectiveObjectId;
import com.tengju.motivation.domain.model.performance.PerformanceObjectiveRepository;
import com.tengju.motivation.domain.model.performance.PerformanceObjectiveTypeEnum;
import com.tengju.motivation.domain.shared.DateType;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.tengju.user.domain.shared.BizException;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: 李大仙
 * @Date: 2021/5/6 10:42 上午
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class PerformanceNewFacade {

    private final MetaHolder metaHolder;
    private final ReportPerformanceRepository reportPerformanceRepository;
    private final PerformanceObjectiveRepository performanceObjectiveRepository;
    private final UserInfoRepository userInfoRepository;

    public List<KVVO> kaTarget(Integer dateTypeVal, String date,String meta) {
        List<UserIdCode> genSecIdCodes = ServletContextUtil.getServletContext().getGenSecIdCodes();
        return secTarget(dateTypeVal,date,genSecIdCodes,meta);
    }

    public List<KVVO> secTarget(Integer dateTypeVal, String date, List<UserIdCode> secIdCodes,String meta) {
        DateType dateType = DateType.form(dateTypeVal);
        Collection<Meta> metas = metaHolder.listMeta(meta).values();
        List<Row> performanceRows;
        LocalDate targetStartDate;
        LocalDate targetEndDate;
        switch (dateType) {
            case DAY:
                performanceRows = reportPerformanceRepository.getKaPerformanceDay(secIdCodes,date);
                targetStartDate = LocalDate.parse(date);
                targetEndDate = LocalDate.parse(date);
                break;
            case WEEK:
                Week week = new Week(LocalDate.parse(date));
                performanceRows = reportPerformanceRepository.getKaPerformanceWeek(secIdCodes,week);
                targetStartDate = week.getStartDate();
                targetEndDate = week.getEndDate();
                break;
            case MONTH:
                com.tengju.data.domain.shared.Month month = new com.tengju.data.domain.shared.Month(CastUtil.castInt(date));
                performanceRows = reportPerformanceRepository.getKaPerformanceMonth(secIdCodes,month);
                targetStartDate = month.getStartDate();
                targetEndDate = month.getEndDate();
                break;
            case QUARTER:
                com.tengju.data.domain.shared.Quarter quarter = new com.tengju.data.domain.shared.Quarter(date);
                performanceRows = reportPerformanceRepository.getKaPerformanceQuarter(secIdCodes,quarter);
                targetStartDate = quarter.getStartDate();
                targetEndDate = quarter.getEndDate();
                break;
            default:
                throw new BizException("日期类型不匹配");
        }
        // 查询用户绩效目标
        List<PerformanceObjectiveObjectId> objectIdList = secIdCodes.stream()
                .map(v -> new PerformanceObjectiveObjectId(v.getValue()))
                .collect(Collectors.toList());
        List<PerformanceObjective> targetList = performanceObjectiveRepository.getByObjectIdAndType(
                objectIdList,
                PerformanceObjectiveTypeEnum.GEN_SEC,
                com.tengju.data.domain.shared.DateUtil.formatDayInt(targetStartDate),
                com.tengju.data.domain.shared.DateUtil.formatDayInt(targetEndDate)
        );
        Row row = new Row();
        if (!CollectionUtils.isEmpty(performanceRows)) {
            row = performanceRows.get(0);
        }
        // 填充绩效目标
        if (!CollectionUtils.isEmpty(targetList)) {
            for (PerformanceObjective performanceObjective : targetList) {
                BigDecimal existTarget = BigDecimal.valueOf(CastUtil.castDouble(row.getValue(performanceObjective.getKey())));
                row.put(performanceObjective.getKey(),existTarget.add(performanceObjective.getValue()));
            }
        }
        return KVAssembler.buildData(metas,row);
    }

    public TableVO secTargetTable(Integer dateTypeVal, String date) {
        DateType dateType = DateType.form(dateTypeVal);
        List<UserIdCode> secIdCodes = ServletContextUtil.getServletContext().getGenSecIdCodes();
        Collection<Meta> metas = metaHolder.listMeta("motivation_target_dashboard").values();
        TableVO table = new TableVO();
        TableAssembler.buildColumns(table,metas);
        table.addColumn(null, ColumnVO.of("showName","服务商",false));
        List<Row> performanceRows;
        LocalDate targetStartDate;
        LocalDate targetEndDate;
        switch (dateType) {
            case DAY:
                performanceRows = reportPerformanceRepository.getTopSecPerformanceDay(secIdCodes,date);
                targetStartDate = LocalDate.parse(date);
                targetEndDate = LocalDate.parse(date);
                break;
            case WEEK:
                Week week = new Week(LocalDate.parse(date));
                performanceRows = reportPerformanceRepository.getTopSecPerformanceWeek(secIdCodes,week);
                targetStartDate = week.getStartDate();
                targetEndDate = week.getEndDate();
                break;
            case MONTH:
                com.tengju.data.domain.shared.Month month = new com.tengju.data.domain.shared.Month(CastUtil.castInt(date));
                performanceRows = reportPerformanceRepository.getTopSecPerformanceMonth(secIdCodes,month);
                targetStartDate = month.getStartDate();
                targetEndDate = month.getEndDate();
                break;
            case QUARTER:
                com.tengju.data.domain.shared.Quarter quarter = new com.tengju.data.domain.shared.Quarter(date);
                performanceRows = reportPerformanceRepository.getTopSecPerformanceQuarter(secIdCodes,quarter);
                targetStartDate = quarter.getStartDate();
                targetEndDate = quarter.getEndDate();
                break;
            default:
                throw new BizException("日期类型不匹配");
        }
        if (CollectionUtils.isEmpty(performanceRows)) {
            performanceRows = new ArrayList<>();
        }

        if (performanceRows.size() < 10) {
            Set<Long> idCodeSet = performanceRows.stream()
                    .map(v -> CastUtil.castLong(v.getValue("bl_sec_id_code")))
                    .collect(Collectors.toSet());
            List<Long> extraIdCodes = secIdCodes.stream()
                    .map(v -> v.getValue())
                    .filter(v -> !idCodeSet.contains(v))
                    .limit(10 - performanceRows.size())
                    .collect(Collectors.toList());
            for (Long extraIdCode : extraIdCodes) {
                Row row = new Row();
                row.put("bl_sec_id_code",extraIdCode);
                performanceRows.add(row);
            }
        }
        //查询用户数据（昵称+星级）
        List<UserIdCode> idCodeList = performanceRows.stream()
                .map(v -> new UserIdCode(CastUtil.castLong(v.getValue("bl_sec_id_code"))))
                .collect(Collectors.toList());
        List<UserInfo> userInfoList = userInfoRepository.batchGetUserInfo(idCodeList);
        Map<Long,UserInfo> userInfoMap =
                CollectionUtils.isEmpty(userInfoList) ?
                        new HashMap<>() :
                        userInfoList.stream()
                                .collect(Collectors.toMap(k -> k.getIdCode().getValue(),v -> v,(v1,v2) -> v1));
        // 查询用户绩效目标
        List<PerformanceObjectiveObjectId> objectIdList = performanceRows.stream()
                .map(v -> new PerformanceObjectiveObjectId(CastUtil.castLong(v.getValue("bl_sec_id_code"))))
                .collect(Collectors.toList());
        List<PerformanceObjective> targetList = performanceObjectiveRepository.getByObjectIdAndType(
                objectIdList,
                PerformanceObjectiveTypeEnum.GEN_SEC,
                com.tengju.data.domain.shared.DateUtil.formatDayInt(targetStartDate),
                com.tengju.data.domain.shared.DateUtil.formatDayInt(targetEndDate)
        );
        Map<Long,List<PerformanceObjective>> targetMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(targetList)) {
            for (PerformanceObjective performanceObjective : targetList) {
                long idCodeVal = performanceObjective.getObjectId().getValue();
                List<PerformanceObjective> idCodeTargetList = targetMap.getOrDefault(idCodeVal,new ArrayList<>());
                idCodeTargetList.add(performanceObjective);
                targetMap.put(idCodeVal,idCodeTargetList);
            }
        }
        // 填充绩效目标&用户昵称
        for (Row performanceRow : performanceRows) {
            Long idCodeVal = CastUtil.castLong(performanceRow.getValue("bl_sec_id_code"));
            List<PerformanceObjective> idCodeTargetList = targetMap.getOrDefault(idCodeVal,new ArrayList<>());
            for (PerformanceObjective performanceObjective : idCodeTargetList) {
                BigDecimal existTarget = BigDecimal.valueOf(CastUtil.castDouble(performanceRow.getValue(performanceObjective.getKey())));
                performanceRow.put(performanceObjective.getKey(),existTarget.add(performanceObjective.getValue()));
            }
            UserInfo userInfo = userInfoMap.get(idCodeVal);
            if (userInfo != null) {
                String showName = userInfo.getBackNickName() + " " + userInfo.starLevel().getShortName() + "(" + idCodeVal + ")";
                performanceRow.put("showName",showName);
            }

            performanceRow.put("id_code",idCodeVal);
        }

        TableAssembler.buildData(table,performanceRows,metas,List.of("id_code","showName"));
        return table;
    }
}

